package com.samehope.ar.socket.strategy;

import com.samehope.ar.socket.annotation.Command;
import com.samehope.ar.socket.constant.CommandEnum;
import com.samehope.ar.socket.support.MessageBody;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.reflections.Reflections;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description: 指令上下文
 * @Author: ZhangLuo
 * @Email: 1946430@qq.com
 */
@Slf4j
@Component
public class CommandContext {

    /**
     * 用于存放世界处理类的地方
     * key: 是实际的指令
     * value: 是实际的处理类
     */
    private static Map<Integer, CommandHandleStrategy> handlers = new ConcurrentHashMap<>();

    /**
     * 扫描包, 发现所有的实际处理类
     */
    static {
        Reflections reflections = new Reflections("com.samehope.ar.socket.strategy.impl");
        Set<Class<?>> classes = reflections.getTypesAnnotatedWith(Command.class);
        for (Class<?> clazz : classes) {
            Command command = clazz.getAnnotation(Command.class);
            CommandEnum value = command.value();
            try {
                handlers.put(value.getCode(), (CommandHandleStrategy) clazz.newInstance());
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
        log.info("WebSocket指令处理实现类加载成功, 加载处理类 {} 个", handlers.size());
    }

    /**
     * 处理接口
     * @param messageBody
     */
    public static void handleCommand(MessageBody messageBody, Channel channel) {
        CommandHandleStrategy handler = handlers.get(messageBody.getCommand());
        if (handler != null) {
            handler.handle(messageBody, channel);
        } else {
            log.error("WebSocket消息, 未找到处理类: command {}, body {}", messageBody.getCommand(), messageBody.getBody());
        }
    }
}
